package org.example.excel;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import org.example.constant.FileName;
import org.example.excel.model.ExcelModel;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;


/**
 * @program: excel-to-file
 * @author: byl
 * @create: 2024-12-20 14:53
 * @Description
 */
public class DemoDataListener implements ReadListener<ExcelModel> {

    /**
     * 每隔5条存储数据库，实际使用中可以100条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 200;
    /**
     * 缓存的数据
     */
    private List<ExcelModel> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
    private List<String> tableHead = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);


    public DemoDataListener() {

    }

    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        for (Map.Entry<Integer, ReadCellData<?>> entry : headMap.entrySet()) {
            tableHead.add(entry.getValue().getStringValue());
        }
    }

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(ExcelModel data, AnalysisContext context) {
        cachedDataList.add(data);
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        String fileName = "xx-lang-";
        String fileNameSuffix = "-conf.yml";
        String fileid = "fileid";
        for (int i = 1; i < 29; i++) {
            JSONObject jsonObject = new JSONObject();
            int finalI = i + 1;
            cachedDataList.forEach(
                    cached -> {
                        Class<? extends ExcelModel> aClass = cached.getClass();
                        try {
                            Field field = aClass.getDeclaredField(fileid+"1");
                            field.setAccessible(true);
                            String key = (String) field.get(cached);
                            Field fieldV = aClass.getDeclaredField(fileid+ finalI);
                            fieldV.setAccessible(true);
                            Object val = fieldV.get(cached);
                            if(val.toString().startsWith("\"")){
                                String string = val.toString();
                                string = string.replaceAll("\"","");
                                if(val.toString().endsWith(",")){
                                    string =  string.substring(0,string.length()-1);
                                }
                                jsonObject.set(key.trim(),string.trim());
                            }else{
                                jsonObject.set(key.trim(),val.toString().trim());

                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    }
            );
            String val = tableHead.get(i);
            String startStr = FileName.LANG_FIELD_MAP.get(val);
            String stringPretty = jsonObject.toStringPretty();
            String quote = quote(stringPretty,true);
            String finalFileVal = startStr + ": " +quote;
            String finalFileName = fileName + startStr + fileNameSuffix;
            FileUtil.writeString(finalFileVal,new File("D:\\nacos\\"+finalFileName), StandardCharsets.UTF_8);
        }
    }

    public static String quote(String string) {
        return quote(string, true);
    }

    public static String quote(String string, boolean isWrap) {
        StringWriter sw = new StringWriter();

        try {
            return quote(string, sw, isWrap).toString();
        } catch (IOException var4) {
            return "";
        }
    }



    public static Writer quote(String str, Writer writer, boolean isWrap) throws IOException {
        if (StrUtil.isEmpty(str)) {
            if (isWrap) {
                writer.write("\"\"");
            }

            return writer;
        } else {
            int len = str.length();
            if (isWrap) {
                writer.write(34);
            }

            for(int i = 0; i < len; ++i) {
                char c = str.charAt(i);
                switch (c) {
                    case '"':
                    case '\\':
                        writer.write("\\");
                        writer.write(c);
                        break;
                    default:
                        writer.write(escape(c));
                }
            }

            if (isWrap) {
                writer.write(34);
            }

            return writer;
        }
    }



    private static String escape(char c) {
        switch (c) {
            case '\b':
                return "\\b";
            case '\t':
                return "\\t";
            case '\n':
                return "";
            case '\u000b':
            default:
                return c >= ' ' && (c < 128 || c > 160) && (c < 8192 || c > 8208) && (c < 8232 || c > 8239) && (c < 8294 || c > 8303) ? Character.toString(c) : HexUtil.toUnicodeHex(c);
            case '\f':
                return "\\f";
            case '\r':
                return "\\r";
        }
    }


    public static void main(String[] args) {
        String str = "1,11,";
        System.out.println(str.substring(0,str.length()-1));
    }
}


